﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace Useful.GUI
{
    public class DataGridViewNullCheckBoxColumn : DataGridViewCheckBoxColumn
    {
        public DataGridViewNullCheckBoxColumn()
        {
            base.CellTemplate = new DataGridViewNullCheckBoxCell();
        }

        public DataGridViewNullCheckBoxColumn(bool threeState)
        {
            base.CellTemplate = new DataGridViewNullCheckBoxCell(threeState);
        }
    }

    public class DataGridViewNullCheckBoxCell : DataGridViewCheckBoxCell
    {
        public DataGridViewNullCheckBoxCell()
        {
        }

        public DataGridViewNullCheckBoxCell(bool threeState)
            : base(threeState)
        {
        }

        private static bool IsIndeterminateState(object value)
        {
            bool res = false;

            if (value != null)
            {
                if (value is bool)
                    res = false;
                else if (value is CheckState)
                    res = (CheckState)value == CheckState.Indeterminate;
                else if (value is int)
                    res = (int)value == 2;
                else if (value is DBNull)
                    res = (DBNull)value == DBNull.Value;
                else
                    throw new ArgumentOutOfRangeException("value", value, "value - не допустимого типа");
            }
            else
                res = true;

            return res;
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            if (!IsIndeterminateState(value))
                base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
            else
            {
                Color c;

                if ((elementState & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
                    c = cellStyle.SelectionBackColor;
                else
                    c = cellStyle.BackColor;

                graphics.FillRectangle(new SolidBrush(c), cellBounds);
                base.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
            }
        }

        public override object EditingCellFormattedValue
        {
            get
            {
                return base.EditingCellFormattedValue;
            }
            set
            {
                CheckState cs = (CheckState)value;

                if (cs == CheckState.Indeterminate)
                    cs = CheckState.Unchecked;

                base.EditingCellFormattedValue = cs;
            }
        }
    }
}